package com.smart.controller;

import java.io.IOException;
import java.io.PrintWriter;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringUtils;
import org.atmosphere.cpr.AtmosphereResource;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.smart.constants.SmartConstants;
import com.smart.dao.UserDAO;
import com.smart.model.AccessToken;
import com.smart.model.MaintenanceManInfo;
import com.smart.model.RepairHandleTemplate;
import com.smart.model.RepairRequest;
import com.smart.model.RepairRequestBriefInfo;
import com.smart.model.template.Parameter;
import com.smart.model.template.RepairHandleData;
import com.smart.service.RepairRequestService;
import com.smart.util.AtmosphereUtils;
import com.smart.util.JPushUtil;
import com.smart.util.JsonUtil;
import com.smart.util.WeixinUtil;

import cn.jpush.api.JPushClient;
import cn.jpush.api.common.resp.APIConnectionException;
import cn.jpush.api.common.resp.APIRequestException;
import cn.jpush.api.push.PushResult;

@RestController
public class RepairController {
	@RequestMapping(value = "/wechat/sumit_repair_request", method = RequestMethod.POST)
	public void addRepairRequest(HttpServletRequest req, HttpServletResponse resp) {
		System.out.println("process repair request");
		PrintWriter pw = null;
		resp.setCharacterEncoding("UTF-8");
		// 从session中取得用户openID
		Object tmp = req.getSession().getAttribute("openId");
		if (tmp == null || tmp.equals("")) {
			System.out.println("no openID in session.");
			return;
		}
		String openID = tmp.toString();
		System.out.println("open_id == " + openID);
		String title = req.getParameter("title");
		String content = req.getParameter("content");
		String[] images = req.getParameterValues("image[]");
		String voice = req.getParameter("voice");
		System.out.println("title == " + title);
		System.out.println("content == " + content);
		try {
			RepairRequestService repairRequestService = new RepairRequestService();
			RepairRequest repairRequest = new RepairRequest();
			repairRequest.setUserID(repairRequestService.getUserIDByOpenID(openID));
			// repairRequest.setOpen_id(openID);
			repairRequest.setTitle(title);
			repairRequest.setContent(content);
			Calendar cal = Calendar.getInstance();
			String mediaPath = req.getServletContext().getRealPath("/") + "media/";
			String datePath = cal.get(Calendar.YEAR) + "/" + (cal.get(Calendar.MONTH) + 1) + "/"
					+ cal.get(Calendar.DAY_OF_MONTH) + "/";
			List<String> imgUrls = new ArrayList<>();
			if (images != null) {
				System.out.println("images.length == " + images.length);
				for (int i = 0; i < images.length; i++) {
					String fileName = WeixinUtil.downloadMediaFromWx(WeixinUtil.getAccessToken().getToken(), images[i],
							mediaPath + "images/" + datePath);
					System.out.println("Download image " + fileName);
					imgUrls.add("media/images/" + datePath + fileName);
				}
			}
			repairRequest.setImages(imgUrls);
			if (!StringUtils.isEmpty(voice)) {
				String fileName = WeixinUtil.downloadMediaFromWx(WeixinUtil.getAccessToken().getToken(), voice,
						mediaPath + "audio/" + datePath);
				System.out.println("Download audio " + fileName);

				repairRequest.setAudio("media/audio/" + datePath + fileName);
			}
			repairRequest.setDate(new Timestamp(System.currentTimeMillis()));
			repairRequest.setStatus(0);
			repairRequestService.addRepairRequest(repairRequest);
			System.out.println("insert into repair_request_record successfully !");
			pw = resp.getWriter();
			pw.print("true");
			pw.flush();
			// send notifications to admin
			AtmosphereUtils.notify("repair", "new request");
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@RequestMapping(value = "/pc/if_exists_unhandled_repair_request", method = RequestMethod.POST)
	public void judgeExitenceOfUnhandledRepairRequest(HttpServletRequest req, HttpServletResponse resp) {
		RepairRequestService repairRequestService = new RepairRequestService();
		PrintWriter pw = null;
		resp.setCharacterEncoding("UTF-8");
		System.out.println("1111111111");
		try {
			boolean existence = repairRequestService.judgeExitenceOfUnhandledRepairRequest();
			System.out.println("existence == " + existence);
			pw = resp.getWriter();
			pw.print(String.valueOf(existence));
			pw.flush();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@RequestMapping(value = "/pc/get_repair_request_list", method = RequestMethod.POST)
	public void getRepairRequestList(HttpServletRequest req, HttpServletResponse resp) {
		RepairRequestService repairRequestService = new RepairRequestService();
		PrintWriter pw = null;
		String status, page, dateFrom, dateTo;
		resp.setCharacterEncoding("UTF-8");
		try {
			status = req.getParameter("status");
			page = req.getParameter("page");
			dateFrom = req.getParameter("dateFrom");
			dateTo = req.getParameter("dateTo");
			HashMap<String, Object> hashMap = null;

			if (status == null || page == null) {
				System.out.println("Parameter status or page is null");
				return;
			} else if ((dateFrom == null && dateTo == null) || (dateFrom.equals("") && dateTo.equals(""))) {
				hashMap = repairRequestService.getRepairRequestList(Integer.parseInt(status), Integer.parseInt(page));
			} else if (dateFrom != null && dateTo != null && (!dateFrom.equals("")) && (!dateTo.equals(""))) {
				hashMap = repairRequestService.getRepairRequestList(Integer.parseInt(status), Integer.parseInt(page),
						dateFrom, dateTo);
			} else {
				System.out.println("Parameter error");
			}

			String json = JsonUtil.toJson(hashMap);
			System.out.println(json);
			pw = resp.getWriter();
			pw.print(json);
			pw.flush();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@RequestMapping(value = "/users/{id}/repairs", method = RequestMethod.GET)
	@ResponseBody
	public List<RepairRequest> getRepairRequestList(@PathVariable("id") int userID, @RequestParam("status") int status,
			@RequestParam("page") int page, @RequestParam("pagesize") int pageSize) {
		RepairRequestService repairRequestService = new RepairRequestService();
		List<RepairRequest> list = null;
		System.out.println("userID == " + userID);
		try {
			list = repairRequestService.getRepairRequestList(userID, status, page, pageSize);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return list;
	}

	@RequestMapping(value = "/users/{id}/repairs", method = RequestMethod.POST)
	@ResponseBody
	public Map<String, Boolean> addRepairRequest(@PathVariable("id") int userID,
			@RequestBody RepairRequest repairRequest) {
		RepairRequestService repairRequestService = new RepairRequestService();
		System.out.println("userID == " + userID);
		Map<String, Boolean> map = new HashMap<>();
		try {
			Boolean result = repairRequestService.addRepairRequest(repairRequest);
			map.put("result", result);
			System.out.println(result);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return map;
	}

	@RequestMapping(value = "/pc/get_repair_request_details", method = RequestMethod.POST)
	public void getRepairRequestDetailsByID(HttpServletRequest req, HttpServletResponse resp) {
		RepairRequestService repairRequestService = new RepairRequestService();
		PrintWriter pw = null;
		int id;
		resp.setCharacterEncoding("UTF-8");
		try {
			id = Integer.parseInt(req.getParameter("id"));
			pw = resp.getWriter();
			RepairRequestBriefInfo info = repairRequestService.getRepairRequestDetailsByID(id);
			String json = JsonUtil.toJson(info);
			System.out.println(json);
			pw.print(json);
			pw.flush();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@RequestMapping(value = "/pc/get_maintenance_man_info_list", method = RequestMethod.POST)
	public void getMaintenanceInfoList(HttpServletRequest req, HttpServletResponse resp) {
		RepairRequestService repairRequestService = new RepairRequestService();
		PrintWriter pw = null;
		resp.setCharacterEncoding("UTF-8");
		try {
			pw = resp.getWriter();
			List<MaintenanceManInfo> list = repairRequestService.getMaintenanceManInfoList();
			String json = JsonUtil.toJson(list);
			System.out.println(json);
			pw.print(json);
			pw.flush();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@RequestMapping(value = "/pc/handle_repair_request", method = RequestMethod.POST)
	public void handleRepairRequest(HttpServletRequest req, HttpServletResponse resp) {
		RepairRequestService repairRequestService = new RepairRequestService();
		int recordID, status, maintenanceManID;
		recordID = Integer.parseInt(req.getParameter("record_id"));
		status = Integer.parseInt(req.getParameter("status"));
		maintenanceManID = Integer.parseInt(req.getParameter("maintenance_man_id"));
		PrintWriter pw = null;
		try {
			System.out.println("handle repair request");
			System.out.println(status + " " + recordID + " " + maintenanceManID);
			repairRequestService.updateRepairRequestRecord(status, recordID, maintenanceManID);
			RepairRequestBriefInfo info = repairRequestService.getRepairRequestBriefInfoByID(recordID);
			sendRepairHandleMsg(info);
			@SuppressWarnings("deprecation")
			JPushClient jpushClient = new JPushClient(SmartConstants.JPUSH_MASTER_SECRET, 
					SmartConstants.JPUSH_APPKEY, 3);
			PushResult result = jpushClient.sendPush(JPushUtil.
					buildPushObject_all_alias_notice(info.getTelphone_num(), "您最近的一次报修申请已被处理"));
			System.out.println(result);
			pw = resp.getWriter();
			pw.print("true");
			pw.flush();
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (APIConnectionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (APIRequestException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	@RequestMapping(value = "/pc/user-notifications/repair")
	@ResponseBody
	public void watch(AtmosphereResource atmosphereResource) {
		System.out.println("add repair listener!!!!!!!!!");
		// suspending resource to keep connection
		AtmosphereUtils.suspend(atmosphereResource, "repair");
		// AtmosphereUtils.notify("repair", "new request");
	}

	private void sendRepairHandleMsg(RepairRequestBriefInfo info) throws SQLException {
		UserDAO userDAO = new UserDAO();
		String openId = userDAO.getOpenIdByUserId(info.getUser_id());
		if (openId == null || openId.isEmpty()) {
			System.out.println("user has no OpenID");
			return;
		}
		Parameter first = new Parameter();
		Parameter keyword1 = new Parameter();
		Parameter keyword2 = new Parameter();
		Parameter keyword3 = new Parameter();
		Parameter keyword4 = new Parameter();
		Parameter keyword5 = new Parameter();
		Parameter remark = new Parameter();

		first.setValue("尊敬的" + info.getUser_name() + "先生/女士，您的报修有新的进展");
		keyword1.setValue(info.getCommunity_name() + info.getBuilding_no() + "号楼" + info.getRoom_no() + "房间");
		keyword2.setValue(info.getTitle());
		DateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
		keyword3.setValue(sdf.format(info.getDate()));
		keyword4.setValue("已指派给维修人员" + info.getMaintenance_man_name() + "，将在3个工作日内上门维修。");
		Calendar cal = Calendar.getInstance();
		cal.setTime(info.getDate());
		cal.add(Calendar.DATE, 3);
		keyword5.setValue(sdf.format(cal.getTime()));
		remark.setValue("上门前工作人员将提前与您预约，请保持电话畅通，谢谢。");
		RepairHandleData repairHandleData = new RepairHandleData();
		repairHandleData.setFirst(first);
		repairHandleData.setKeyword1(keyword1);
		repairHandleData.setKeyword2(keyword2);
		repairHandleData.setKeyword3(keyword3);
		repairHandleData.setKeyword4(keyword4);
		repairHandleData.setKeyword5(keyword5);
		repairHandleData.setRemark(remark);
		RepairHandleTemplate repairHandleTemplate = new RepairHandleTemplate();
		repairHandleTemplate.setData(repairHandleData);
		repairHandleTemplate.setTemplate_id("CfG-uHn5qqwDfFtg7fs0-uuOs34rFwO3eiGQxNaVQ44");
		repairHandleTemplate.setTouser(openId);
		AccessToken token = WeixinUtil.getAccessToken();
		String message = JsonUtil.toJson(repairHandleTemplate);
		System.out.println(message);
		WeixinUtil.sendTemplateMessage(token, message);
	}
}
